home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Languages / MacGofer 0.22d / MacGofer Sources / mac_windows.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-07  |  43.6 KB  |  1,923 lines  |  [TEXT/MPS ]

  1. /*****************************************************************************
  2.  
  3.   mac_windows.c:  Copyright (c) Kevin Hammond 1993.   All rights reserved.
  4.   
  5.   This module contains code to handle window display, update, creation etc. 
  6.  
  7. *****************************************************************************/
  8.  
  9. #include "mac.h"
  10. #include <string.h>
  11. #include <AppleEvents.h>
  12.  
  13. #pragma segment Windows
  14.  
  15. extern CursHandle watchcurs;                /* Watch cursor */
  16. extern EventRecord myEvent;            /* Global Event Record */
  17. extern Boolean CIAvailable;            /* Are colour icons available */
  18.  
  19.  
  20. /*
  21.    Window-handling routines.
  22. */
  23.  
  24.  
  25. #define NUM_WINDOWS         64    /* How many windows at a maximum             */
  26. #define NUM_SYS_WINDOWS     2    /* How many of these are system windows         */
  27. #define ILLEGAL_WINDOW         (-1)    /* The value that means "not one of our windows"     */
  28.  
  29.  
  30. struct WindowStruct WindowRec[NUM_WINDOWS];    /* The window record array     */
  31.  
  32. int thefrontwindow = ILLEGAL_WINDOW;        /* FrontWindow() cache        */
  33. DescType savemethod = kAEAskUser;               /* How to save files on quit    */
  34.  
  35. /* Forward declarations */
  36. extern char *safemalloc();
  37.  
  38. extern short findmenuitem();
  39.  
  40. extern Boolean scrapVisible;
  41.  
  42. extern Boolean isVolLocked(), isUserLocked();
  43.  
  44.  
  45.  
  46. /****************************************************************************
  47.  
  48.     Window attribute setting.
  49.  
  50. ****************************************************************************/
  51.  
  52.   
  53. /*
  54.    This routine is called when a window is saved.  The SAVED flag is 
  55.    set, and the appropriate menu item reverted to normal.
  56. */
  57.  
  58. saved(i)
  59. {
  60.   if(isEditWindow(i) && OPEN(i) && !SAVED(i) && FILENAME(i) != NIL)
  61.     {
  62.       char wtitle[256];
  63.       short menuitem;
  64.       getwtitle(WINDOW(i),wtitle);
  65.       if((menuitem = findmenuitem(Menu_Window,3,1024,wtitle)) >= 3)
  66.         SetItemStyle(Menu_Window,menuitem,normal);
  67.     }
  68.   
  69.   if(isLegalWindow(i))
  70.     {
  71.       FLAGS(i) |= WSAVED;
  72.       FLAGS(i) &= ~WVIRGIN;
  73.     }
  74. }
  75.  
  76.  
  77. /*
  78.    This routine is called when any changes are made to a TE
  79.    buffer.  The SAVED flag is unset, and the appropriate menu
  80.    item underlined.
  81.    
  82.    We do not bother underlining already changed windows, nor do
  83.    we record that the worksheet has been changed.  The worksheet
  84.    is purely a scratch area, so loss should not be as important
  85.    as a document.
  86.    
  87.    Changed this to record worksheet changes -- KH, V 0.04.
  88. */
  89.  
  90.  
  91. changed(i)
  92. {
  93.   if(isEditWindow(i) && OPEN(i))
  94.     {
  95.       if(SAVED(i))
  96.         {
  97.           char wtitle[256];
  98.           short menuitem;
  99.           getwtitle(WINDOW(i),wtitle);
  100.           if((menuitem = findmenuitem(Menu_Window,3,1024,wtitle)) >= 3)
  101.             SetItemStyle(Menu_Window,menuitem,underline);
  102.           FLAGS(i) &= ~WSAVED;
  103.         }
  104.     }      
  105. }
  106.  
  107.  
  108. /*
  109.    Records that a window has been created (or OPENED).
  110. */
  111.  
  112. opened(i)
  113. {
  114.   if(isLegalWindow(i))
  115.     FLAGS(i) |= WOPEN;
  116. }
  117.  
  118.  
  119. /*
  120.   A window has been closed.
  121.   The worksheet and clipboard are never closed this way.
  122. */
  123.  
  124. closed(i)
  125. {
  126.   if(isDocumentWindow(i))
  127.     FLAGS(i) &= ~WOPEN;
  128. }
  129.  
  130. /*
  131.    This sets the version number for a window.
  132.    
  133.    Versions are used if there are multiple windows with the
  134.    same name.
  135. */
  136.  
  137. setversion(i,vers)
  138. {
  139.   if(isDocumentWindow(i))
  140.     {
  141.       FLAGS(i) &= ~WVERSMASK;
  142.       FLAGS(i) |= (vers << (WVERS-1)) & WVERSMASK;
  143.     }
  144. }
  145.  
  146.  
  147.  
  148. /*
  149.    Set the title and filename of an existing window record.
  150.    
  151.    Adjust other windows with the same filename
  152.    to reflect the version changes.
  153. */
  154.  
  155.  
  156. setwindowtitle(windex,title)
  157. int windex;
  158. char *title;
  159. {
  160.   char *newtitle = safemalloc(strlen(title)+1);
  161.   strcpy(newtitle,title);
  162.   if(FILENAME(windex) != NIL)
  163.     free(FILENAME(windex));
  164.   FILENAME(windex) = newtitle;
  165.   setwtitle(WINDOW(windex),title);
  166.  
  167.   if(findHighestVersion(title) > 0)
  168.     resetversions(title,windex);
  169. }
  170.  
  171.  
  172. /****************************************************************************
  173.  
  174.     Locating windows according to various criteria.
  175.  
  176. ****************************************************************************/
  177.  
  178.  
  179. /*
  180.    Find the window if it is one of mine.
  181. */
  182.  
  183. findMyWindow(window)
  184. WindowPtr window;
  185. {
  186.   int w = GetWRefCon(window)-1;
  187.   if(!isLegalWindow(w) || !OPEN(w))
  188.     w = ILLEGAL_WINDOW;
  189.  
  190.   return(w);
  191. }
  192.  
  193.  
  194. /*
  195.    Find a window corresponding to a file.
  196.    Use the window title rather than the recorded
  197.    filename if looking for a named window
  198.    (e.g. because selected from the Window menu).
  199. */
  200.  
  201. int findMyWindowName(name,volnum,dirID,usewtitle)
  202. char *name;
  203. short volnum;
  204. long dirID;
  205. Boolean usewtitle;
  206. {
  207.   int i;
  208.   char *fname;
  209.   char wname[256];
  210.  
  211.   for( i = 0; i < NUM_WINDOWS; ++i )
  212.     if (OPEN(i))
  213.       {
  214.         if(usewtitle)
  215.       {
  216.         getwtitle(WINDOW(i),wname);
  217.         fname = wname;
  218.       }
  219.     else
  220.       fname = FILENAME(i);
  221.       
  222.     if(equalfiles(name,fname) && (usewtitle || (VREFNUM(i) == volnum && DIRID(i) == dirID)))
  223.           return(i);
  224.       }
  225.  
  226.    return( ILLEGAL_WINDOW );
  227. }
  228.  
  229.  
  230.  
  231. /****************************************************************************
  232.  
  233.     Window attribute testing.
  234.  
  235. ****************************************************************************/
  236.  
  237.  
  238. /*
  239.     Is this a valid window
  240. */
  241.  
  242. isValidWindow(whichWindow)
  243. WindowPtr whichWindow;
  244. {
  245.   int w = findMyWindow(whichWindow);
  246.   return(isLegalWindow(w));
  247. }
  248.  
  249.  
  250. /*
  251.     Is the window iconic.
  252. */
  253.  
  254. int iconic(windex)
  255. int windex;
  256. {
  257.    return(isLegalWindow(windex) && ICONIC(windex));
  258. }
  259.  
  260.  
  261. /*
  262.    Can the window be edited?
  263.    
  264.    Currently true for all non-scrap windows.
  265. */
  266.  
  267. isEditWindow(windex)
  268. int windex;
  269. {
  270.   return(isLegalWindow(windex) && !isScrapWindow(windex) && !iconic(windex));
  271. }
  272.  
  273.  
  274. /*
  275.    Is the window reference in a legal range.
  276. */
  277.  
  278. isLegalWindow(windex)
  279. int windex;
  280. {
  281.   return(windex >= 0 && windex < NUM_WINDOWS);
  282. }
  283.  
  284.  
  285. /*
  286.   Is this the scrap window.
  287. */
  288.  
  289. isScrapWindow(windex)
  290. int windex;
  291. {
  292.   return(windex == scrap);
  293. }
  294.  
  295.  
  296. /*
  297.    Is this a user document window
  298. */
  299.  
  300. isDocumentWindow(windex)
  301. int windex;
  302. {
  303.   /* ignore worksheet and clipboard windows */
  304.   return(windex > NUM_SYS_WINDOWS-1 && windex < NUM_WINDOWS);
  305. }
  306.  
  307.  
  308.  
  309. /****************************************************************************
  310.  
  311.    Initialise Gofer Windows.
  312.    
  313.    Set up the window record and create the initial windows -- worksheet and scrap.
  314.    Initially the scrap (clipboard) window is hidden.  The scrap is not added to
  315.    the Window list in the window menu, but all other windows including the Worksheet
  316.    are added.
  317.  
  318. ****************************************************************************/
  319.  
  320. Init_Gofer_Windows()
  321. {
  322.   int i;
  323.   
  324.   for( i=0; i < NUM_WINDOWS; ++i)
  325.     closed(i);
  326.   
  327.   /* The order of opening determines the indexes of these windows. */   
  328.   (void) CreateNewWindow(Res_OpenClipboard,"Clipboard",FALSE,FALSE,DONT_POSITION,FALSE);
  329.   (void) CreateNewWindow(Res_OpenWorksheet,"Worksheet",TRUE,TRUE,DONT_POSITION,TRUE);
  330.  
  331.   /*
  332.      Don't wrap worksheet lines -- this way, execution output is not "lost".
  333.      Humayan changed this "for consistency", but Don didn't like it!
  334.   */
  335.   
  336.   (*TEHANDLE(worksheet))->crOnly = 0;
  337.  
  338.   /* The scrap is always locked */  
  339.   FLAGS(scrap) |= WVLOCKED;
  340. }
  341.  
  342.  
  343. /****************************************************************************
  344.  
  345.     These routines iconise/deiconise windows (collapse windows
  346.     to icons or vice-versa).
  347.     
  348. ****************************************************************************/
  349.  
  350.  
  351. static CIconHandle CWindowIcon = NIL;
  352. static Handle      WindowIcon  = NIL;
  353.  
  354. /*
  355.     Initialise the Icon.
  356. */
  357.  
  358.  
  359. InitWIcon()
  360. {
  361.   if (CIAvailable && CWindowIcon == NIL )
  362.     CWindowIcon = GetCIcon(Res_IconWindow);
  363.  
  364.   if(WindowIcon == NIL)
  365.     WindowIcon = GetIcon(Res_IconWindow);
  366. }
  367.  
  368.  
  369.  
  370. /*
  371.     Create a new iconic window and position it
  372.     if required.
  373. */
  374.  
  375.  
  376. CreateIconWindow(windex,doposition)
  377. int windex;
  378. Boolean doposition;
  379. {
  380.   static Point position = {0,0};
  381.   
  382.   if (isLegalWindow(windex) && ICONWINDOW(windex) == NIL)
  383.     {
  384.       GrafPtr SavePort;
  385.       PicHandle IconPic;
  386.       
  387.       ICONWINDOW(windex) = GetNewWindow(Res_IconiseWindow, NIL, (WindowPtr) -1);
  388.       SetWRefCon(ICONWINDOW(windex),windex+1);
  389.  
  390.       GetPort(&SavePort);
  391.       SetPort(ICONWINDOW(windex));
  392.  
  393. #if 0
  394.       IconPic = OpenPicture(&ICONWINDOW(windex)->portRect);
  395.       UpdateIconWindow(ICONWINDOW(windex));
  396.       ClosePicture();
  397.       SetWindowPic(ICONWINDOW(windex),IconPic);
  398. #endif
  399.  
  400.       /* Now position the icon, if requested */      
  401.       if(doposition)
  402.         {
  403.       Rect screen;
  404.       
  405.       screen = qd.screenBits.bounds;
  406.           position.h += 40;
  407.           if(position.h > screen.right)
  408.             {
  409.               position.h = screen.left+5;
  410.               position.v += 40;
  411.           if(position.v > screen.bottom)
  412.             position.v = screen.top + 25;
  413.         }
  414.           else if (position.h < screen.left+5)
  415.             position.h = screen.left+5;
  416.  
  417.           if(position.v < screen.top+25 || position.v > screen.bottom - 40)
  418.             {
  419.           position.v = screen.top + 25;
  420.               position.h = screen.left+5;
  421.         }
  422.       
  423.           MoveWindow(ICONWINDOW(windex),position.h,position.v,false);
  424.         }
  425.       SetPort(SavePort);
  426.    }
  427. }
  428.  
  429.  
  430.  
  431. /*
  432.     Turn a Window into its Iconic form
  433. */
  434.  
  435. IconiseWindow(windex)
  436. int windex;
  437. {
  438.   if (isLegalWindow(windex) && !iconic(windex))
  439.     {
  440.       CreateIconWindow(windex,TRUE);
  441.       HideWindow(WINDOW(windex));
  442.       SendBehind(ICONWINDOW(windex),NIL);
  443.       SendBehind(WINDOW(windex),NIL);
  444.       ShowWindow(ICONWINDOW(windex));
  445. /*      SelectWindow(ICONWINDOW(windex));*/
  446.       FLAGS(windex) |= WICONIC;
  447.       AdjustMenus(TRUE);
  448.     }
  449. }
  450.  
  451.  
  452. /*
  453.     Turn an Iconic Window back into a normal window form.
  454. */
  455.  
  456. DeIconiseWindow(windex)
  457. int windex;
  458. {
  459.   if (isLegalWindow(windex) && iconic(windex))
  460.     {
  461.       HideWindow(ICONWINDOW(windex));
  462.       ShowWindow(WINDOW(windex));
  463.       SelectWindow(WINDOW(windex));
  464.       SendBehind(ICONWINDOW(windex),NIL);
  465.       FLAGS(windex) &= ~WICONIC;
  466.       AdjustMenus(TRUE);
  467.     }
  468. }
  469.  
  470.  
  471. /* 
  472.     Iconise all windows.
  473. */
  474.  
  475. IconiseAll()
  476. {
  477.   int i;
  478.   for( i = 0; i < NUM_WINDOWS; ++i)
  479.     if(OPEN(i))
  480.       IconiseWindow(i);
  481. }
  482.  
  483.  
  484.  
  485. /****************************************************************************
  486.  
  487.     Window Creation.
  488.     
  489. ****************************************************************************/
  490.  
  491.  
  492. /*
  493.    Get a window record and initialise it.
  494.    Again, I'm seriously paranoid.
  495. */
  496.  
  497. int CreateMyWindow()
  498. {
  499.   int i;
  500.  
  501.   for(i=0; i < NUM_WINDOWS; ++i)
  502.     if(EMPTY(i))
  503.       {
  504.     initWindowRec(i);
  505.         opened(i);
  506.     return(i);
  507.       }
  508.   AbortError("","No more windows can be created -- Please close some open windows first");
  509.   return(ILLEGAL_WINDOW);
  510. }
  511.  
  512.  
  513. /*
  514.     Initialse the window record for window "i".
  515. */
  516.  
  517. initWindowRec(i)
  518. int i;
  519. {
  520.   FILENAME(i) =        NIL;
  521.   WINDOW(i) =        NIL;
  522.   ICONWINDOW(i) =    NIL;
  523.   TEHANDLE(i) =        NIL;
  524.   TELOCK(i) =        0;
  525.   HSCROLL(i) =        NIL;
  526.   VSCROLL(i) =        NIL;
  527.   VREFNUM(i) =        0;
  528.   DIRID(i) =        0;
  529.   FLAGS(i) =        (WSAVED | WVIRGIN);
  530. }
  531.  
  532.  
  533.  
  534. /*
  535.    Position a new window nicely (...or so we hope).
  536.    Note that this assumes we have a new window, with the application font set
  537.    For best results, the window should not be visible.
  538. */
  539.  
  540. #define POSITION_NUM_WINDOWS    4
  541. #define POSITION_WINDOW_DELTAH    8
  542. #define POSITION_WINDOW_DELTAV    4
  543. #define POSITION_SCREEN_INSET    4
  544.  
  545. void PositionNewWindow(window,positionIndex)
  546. WindowPtr window;
  547. short positionIndex;
  548. {
  549.   Point offsetPt;
  550.   Rect windowR;
  551.   FontInfo sysFontInfo;
  552.   GrafPtr saveport;
  553.  
  554.   /* Wrap position index so at least POSITION_NUM_WINDOWS windows can be shown neatly */
  555.   positionIndex = (positionIndex % POSITION_NUM_WINDOWS) + 1;
  556.  
  557.   /* We need a grafport so we can do some detective work */
  558.   GetPort(&saveport);
  559.   SetPort(window);
  560.  
  561.   /* Get system font height */
  562.   TextFont(systemFont);
  563.   GetFontInfo(&sysFontInfo);
  564.  
  565.   /* Clean up */
  566.   TextFont(applFont);
  567.   SetPort(saveport);
  568.  
  569.   /* Calculate the offset between windows */
  570.   offsetPt.v = POSITION_WINDOW_DELTAV + (sysFontInfo.ascent + sysFontInfo.descent + sysFontInfo.leading);
  571.   offsetPt.h = offsetPt.v / 2;
  572.  
  573.   /* Figure window rect (on the main screen if multiple monitors) */
  574.   windowR = qd.screenBits.bounds;
  575.   InsetRect(&windowR, POSITION_SCREEN_INSET, POSITION_SCREEN_INSET);
  576.  
  577.   /* Offset the window to the appropriate position */
  578.   windowR.left += offsetPt.h * (positionIndex - 1);
  579.   windowR.top += GetMBarHeight() + (offsetPt.v * positionIndex);
  580.  
  581.   /* And indent the right edge for ease in switching between windows */
  582.   windowR.right -= POSITION_WINDOW_DELTAH * (POSITION_NUM_WINDOWS - positionIndex);
  583.  
  584.   /* Do the real work */
  585.   MoveWindow(window, windowR.left, windowR.top, false);
  586.   SizeWindow(window, windowR.right - windowR.left, windowR.bottom - windowR.top, false);
  587. }
  588.  
  589.  
  590. /*
  591.    Create a new window of the given resource type called fname.
  592.    Show it and add it to the window menu if requested.
  593. */
  594.  
  595. int CreateNewWindow(windowtype,fname,doshow,windowmenu,doposition,fittoviewrect)
  596. char *fname;
  597. Boolean doshow, windowmenu, doposition,fittoviewrect;
  598. {
  599.   int windex;
  600.   extern short currentfnum, currentfsize;
  601.   WindowPtr whichWindow;
  602.   
  603.   SetCursor(*watchcurs);
  604.   
  605.   windex = CreateMyWindow();
  606.   whichWindow = GetNewWindow(windowtype,NIL, (WindowPtr)-1);
  607.   WINDOW(windex) = whichWindow;
  608.  
  609.   /* Write into the new window */
  610.   SetPort(whichWindow);
  611.  
  612.   /* If requested, position the window neatly */
  613.   if (doposition)
  614.     PositionNewWindow(whichWindow, windex - NUM_SYS_WINDOWS);
  615.  
  616.   /* If the window can be zoomed, set up its zoom rectangles */
  617.   if ( ((WindowPeek)whichWindow)->spareFlag )
  618.     {
  619.       WStateDataHandle stateDataH = (WStateDataHandle)((WindowPeek)whichWindow)->dataHandle;
  620.  
  621.       (**stateDataH).stdState = qd.screenBits.bounds;
  622.       (**stateDataH).stdState.top += 38; /* Note: this should probably be set dynamically */
  623.       InsetRect(&(**stateDataH).stdState, POSITION_SCREEN_INSET, POSITION_SCREEN_INSET);
  624.  
  625.       (**stateDataH).userState = whichWindow->portRect;
  626.       LocalToGlobalRect(&(**stateDataH).userState);
  627.     }
  628.  
  629.   /* Set up text characteristics */
  630.   TextFont(currentfnum);
  631.   TextSize(currentfsize);
  632.  
  633.   /* Open a TE Window  */
  634.   NewTERec(windex,fittoviewrect);
  635.  
  636.   /*  Horizontal scroll bar */
  637.   HSCROLL(windex) = GetNewControl( Res_HScroll_bar, whichWindow);
  638.   
  639.   /*  Vertical scroll bar */
  640.   VSCROLL(windex) = GetNewControl( Res_VScroll_bar, whichWindow);
  641.  
  642.   /* Size the scroll bars */
  643.   ScrollHControl(HSCROLL(windex),whichWindow);
  644.   ScrollVControl(VSCROLL(windex),whichWindow);
  645.  
  646.  
  647.   /* Set the window title and reference */
  648.   setwtitle(whichWindow,fname);
  649.   FILENAME(windex) = safemalloc(strlen(fname)+1);
  650.   strcpy(FILENAME(windex),fname);
  651.   SetWRefCon(whichWindow,windex+1);
  652.  
  653.  
  654.   /* Add this window to the window menu if required */
  655.   if(windowmenu)
  656.     {
  657.       short mitems = CountMItems(Menu_Window);
  658.       char itembuf[256];
  659.       if(mitems < 10 + 3)
  660.         {
  661.           sprintf(itembuf,"/%c%s",mitems+'0'-3,fname);
  662.           insmenuitem(Menu_Window,itembuf,mitems);
  663.     }
  664.       else
  665.         insmenuitem(Menu_Window,fname,mitems);
  666.       setwindowtitle(windex,fname);
  667.     }
  668.  
  669.   /* Show the window if required */
  670.   if(doshow)
  671.     {
  672.       ShowWindow(whichWindow);
  673.       DrawGrowIcon(whichWindow);
  674.       DrawGoferIcons(windex);
  675.       DrawControls(whichWindow);
  676.       ValidRect(&whichWindow->portRect);
  677.     }      
  678.  
  679.   InitCursor();
  680.   return(windex);
  681. }
  682.  
  683.  
  684.  
  685. /*
  686.   Create a new untitled window.
  687. */
  688.  
  689.  
  690. newUntitledWindow()
  691. {
  692.   static int num_created = 0;
  693.   char file[20];
  694.   sprintf(file,"Untitled%d",++num_created);
  695.   (void) CreateNewWindow(Res_OpenWindow,file,TRUE,TRUE,AUTO_POSITION,FALSE);
  696. }
  697.  
  698.  
  699. /****************************************************************************
  700.  
  701.     Handling multiple windows with the same name.
  702.     
  703. ****************************************************************************/
  704.  
  705.  
  706. /*
  707.    Return the highest version of a file.
  708. */
  709.  
  710. findHighestVersion(title)
  711. char *title;
  712. {
  713.   int i;
  714.   int version = -1;
  715.  
  716.   for(i=0; i < NUM_WINDOWS; ++i)
  717.     if(OPEN(i))
  718.       {
  719.     if(equalfiles(title,FILENAME(i)))
  720.       setversion(i,++version);
  721.       }
  722.  
  723.   return(version);
  724. }
  725.  
  726.  
  727. /*
  728.    Reset all version numbers.  Don't add a version number
  729.    to the name if windex is ILLEGAL_WINDOW.
  730. */
  731.  
  732. resetversions(name,windex)
  733. char *name;
  734. int windex;
  735. {
  736.   char wtitle[256];
  737.   int i, version = 0;
  738.   char num[5];
  739.   short menuitem;
  740.   Boolean simpletitle = windex == ILLEGAL_WINDOW && 
  741.                         findHighestVersion(name) <= 0;
  742.  
  743.   
  744.   for(i=0; i < NUM_WINDOWS; ++i)
  745.     if(OPEN(i))
  746.       {
  747.     if(equalfiles(name,FILENAME(i)))
  748.       {
  749.         getwtitle(WINDOW(i),wtitle);
  750.             menuitem = findmenuitem(Menu_Window,3,1024,wtitle);
  751.  
  752.             /* Reset the window title */
  753.         strcpy(wtitle,name);
  754.             if(!simpletitle)
  755.           {
  756.             sprintf(num,":%d",VERSION(i)+1);
  757.             strcat(wtitle,num);
  758.               }
  759.  
  760.         setwtitle(WINDOW(i),wtitle);
  761.         setitem(Menu_Window,menuitem,wtitle);
  762.       }
  763.       }
  764. }
  765.  
  766.  
  767.  
  768. /****************************************************************************
  769.  
  770.     Closing and disposing of windows.
  771.     
  772. ****************************************************************************/
  773.  
  774.  
  775. /*
  776.     Close a window.
  777.     Return FALSE if cancelled, otherwise TRUE.
  778. */
  779.  
  780.  
  781. Boolean closethewindow(w,s)
  782. int w;
  783. char *s;
  784. {
  785.   Boolean cancelled = FALSE;
  786.  
  787.   if(isDocumentWindow(w))
  788.     {
  789.       if(savemethod != kAENo && CHANGED(w))
  790.         {
  791.           if((savemethod == kAEAskUser && (cancelled = shouldsavedialog(w,s)) == OK))
  792.             {
  793.           SetCursor(*watchcurs);
  794.               if(!save(w))
  795.             return(FALSE);
  796.         }
  797.           else if (cancelled == CANCEL)
  798.             return(FALSE);
  799.     }
  800.       CloseAWindow(w);
  801.     }
  802.   else if(isScrapWindow(w) && scrapVisible)
  803.     showhideclipboard();
  804.  
  805.   return(TRUE);
  806. }
  807.  
  808.  
  809. /*
  810.     Close all windows.
  811.     Return FALSE if cancelled, otherwise TRUE.
  812. */
  813.  
  814. Boolean closeallwindows()
  815. {
  816.   int i;
  817.   
  818.   SetCursor(*watchcurs);
  819.  
  820.   for(i = 0; i < NUM_WINDOWS; ++i)
  821.     if(OPEN(i))
  822.       {
  823.         if(!closethewindow(i,"quitting"))
  824.         return(FALSE);
  825.         SetCursor(*watchcurs);
  826.       }
  827.  
  828.   return(TRUE);
  829. }
  830.  
  831.  
  832.  
  833. /*
  834.     Close a window.
  835.   
  836.     Reset versions and delete it from the window menu if necessary.
  837. */
  838.  
  839. static char name[256];
  840.  
  841. CloseAWindow(windex)
  842. int        windex;
  843. {
  844.   if (isLegalWindow(windex) && OPEN(windex))
  845.     {
  846.       /* Be careful when closing iconic windows! */
  847.       WindowPtr  whichWindow = iconic(windex)?ICONWINDOW(windex):WINDOW(windex);
  848.       short menuitem, mitems;
  849.  
  850.       /* Remove the window from the window menu if necessary */
  851.       getwtitle(WINDOW(windex),name);
  852.       menuitem = findmenuitem(Menu_Window,3,1024,name);
  853.       if(menuitem >= 3 && menuitem <= 1027)
  854.         {
  855.       char itemstring[256];
  856.       char keyequiv[3];
  857.           DelMenuItem(Menu_Window,menuitem);
  858.       mitems = CountMItems(Menu_Window);
  859.       while(menuitem < 10+4 && menuitem < mitems+1)
  860.         {
  861.           sprintf(itemstring,"/%c",menuitem+'0'-4);
  862.           getitem(Menu_Window,menuitem,itemstring+2);
  863.               DelMenuItem(Menu_Window,menuitem);
  864.           insmenuitem(Menu_Window,itemstring,menuitem-1);
  865.           ++menuitem;
  866.         }
  867.     }
  868.     
  869.       /* 
  870.          Disposing the window causes the window to be deactivated
  871.          and another window to be activated.  To avoid referencing
  872.      a dead window in the deactivate we first hide the window,
  873.      then handle the activate/deactivate explicitly.
  874.      
  875.      The Mac interface model ensures no other activate/deactivate will 
  876.      intervene -- if one was outstanding, it would have been presented
  877.      before this close event.  To be certain, we flush all activate
  878.      events, anyway.
  879.       */
  880.       
  881.       FlushEvents(activMask,0);
  882.  
  883.       /*
  884.          Now we hide the window, which will generate two activate events:
  885.          first a deactivate for the window being hidden, 
  886.      then an activate for the window being brought to the front.
  887.       */
  888.      
  889.       HideWindow(whichWindow);
  890.       
  891.       thefrontwindow = ILLEGAL_WINDOW;
  892.       
  893.       /* Mark the window as closed */
  894.       closed(windex);
  895.  
  896.       if (EventAvail(activMask, &myEvent))
  897.         {
  898.       if (myEvent.what == activateEvt && (WindowPtr)myEvent.message == whichWindow)
  899.         (void) GetNextEvent(activMask, &myEvent);
  900.  
  901.         SetMenus(FALSE,windex);
  902.     }
  903.  
  904.  
  905.       if(FILENAME(windex) != NIL)
  906.      resetversions(FILENAME(windex),ILLEGAL_WINDOW);
  907.  
  908.       if(FILENAME(windex)!=NIL)
  909.         {
  910.           free(FILENAME(windex));
  911.           FILENAME(windex)=NIL;
  912.     }
  913.  
  914.       if(TEHANDLE(windex)!=NIL)
  915.         {
  916.           TEDispose(TEHANDLE(windex));
  917.           TEHANDLE(windex) = NIL;
  918.     }
  919.  
  920.       /* Forget the main window */
  921.       SetWRefCon(WINDOW(windex),0);
  922.       DisposeWindow(WINDOW(windex));
  923.  
  924.       /* and do the same for the icon window */
  925.       if(ICONWINDOW(windex)!=NIL)
  926.         {
  927.           SetWRefCon(ICONWINDOW(windex),0);
  928.       /* Also disposes some necessary controls?  KH */
  929. #if 0
  930.       DisposeWindow(ICONWINDOW(windex));
  931. #endif
  932.         }
  933.  
  934.       initWindowRec(windex);
  935.     }
  936. }
  937.  
  938.  
  939. /****************************************************************************
  940.  
  941.     Resizing windows.
  942.     
  943. ****************************************************************************/
  944.  
  945. void ValidateGrowIcon()
  946. /* Validates the current window's grow icon (assumes the current port is a window) */
  947. {
  948.   Rect growIconR;
  949.  
  950.   growIconR = qd.thePort->portRect;
  951.   growIconR.left = growIconR.right - (SCROLLBARWIDTH - 1);
  952.   growIconR.top = growIconR.bottom - (SCROLLBARWIDTH - 1);
  953.   ValidRect(&growIconR);
  954. }
  955.  
  956.  
  957. /*
  958.   Resize a window.
  959.   
  960.   Handles interpreter-created windows as well as application windows.
  961. */
  962.  
  963.  
  964. ResizeTheWindow(whichWindow)
  965. WindowPtr  whichWindow;
  966. {
  967.   WindowPtr  SavePort;
  968.   int windex = findMyWindow(whichWindow);
  969.   Rect pr = whichWindow->portRect;
  970.   
  971.   if(iconic(windex))
  972.     return;
  973.       
  974.   SetCursor(*watchcurs);
  975.       
  976.   GetPort(&SavePort);                      /* Save the current port */
  977.   SetPort(whichWindow);                    /* Set the port to my window */
  978.  
  979.   /* This is rather clumsy -- Update calls would be better */
  980.   EraseRect(&pr);                          /* Erase the new window area */
  981.   InvalRect(&pr);                          /* Set to update the new window area */
  982.  
  983.   DrawGrowIcon(whichWindow);      
  984.  
  985.   if (isLegalWindow(windex))
  986.     {
  987.       TEHandle teh = TEHANDLE(windex);
  988.       short first;
  989.  
  990.       DrawGoferIcons(windex);      
  991.  
  992.       HLockHigh((Handle)teh);
  993.       first = (*teh)->lineStarts[GetCtlValue(VSCROLL(windex)) - 1];
  994.       CalculateTERects(&(*teh)->viewRect, &(*teh)->destRect, (*teh)->lineHeight, windex==worksheet);
  995.       HUnlock((Handle)teh);
  996.  
  997.       ScrollHControl(HSCROLL(windex),whichWindow);
  998.       ScrollVControl(VSCROLL(windex),whichWindow);
  999.       
  1000.       TECalText(teh);
  1001.       AdjustScrollBars(windex);
  1002.  
  1003.       ScrollCharacter(windex,first,FALSE);
  1004.     }
  1005.       
  1006.   SetPort(SavePort);                       /* Restore the old port */
  1007.   InitCursor();
  1008. }
  1009.  
  1010.  
  1011.  
  1012.  
  1013. /*
  1014.   Resize Horizontal scrollbars.
  1015. */
  1016.  
  1017. ScrollHControl(HControl,whichWindow)
  1018. ControlHandle HControl;
  1019. WindowPtr whichWindow;
  1020. {
  1021.   Rect tempRect, temp2Rect;
  1022.   short Index;
  1023.   int windex = findMyWindow(whichWindow);
  1024.  
  1025.   if (isLegalWindow(windex) && HControl != NIL)      /* Only do if the control is valid */
  1026.     {
  1027.       HLockHigh((Handle)HControl);                   /* Lock the handle while we use it */
  1028.       tempRect = (*HControl)->contrlRect;            /* Get the last control position */
  1029.       tempRect.top = tempRect.top - 4;               /* Widen the area to update */
  1030.       tempRect.right = tempRect.right + 16;          /* Widen the area to update */
  1031.       InvalRect(&tempRect);                          /* Flag old position for update routine */
  1032.       tempRect = (*HControl)->contrlRect;            /* Get the last control position */
  1033.       temp2Rect = whichWindow->portRect;             /* Get the window rectangle */
  1034.       Index = temp2Rect.right - temp2Rect.left - 13; /* Get the scroll area width */
  1035.  
  1036.       /* The scrap has no icons */
  1037.       if(windex == scrap)
  1038.         /* SKIP */;
  1039.  
  1040.       /* The worksheet only has one icon */    
  1041.       else if(windex == worksheet)
  1042.         {
  1043.           tempRect.left = SMALLICONWIDTH-1;          /* Pin at left edge after locked icon */
  1044.           Index -= SMALLICONWIDTH-1;
  1045.     }
  1046.  
  1047.       else
  1048.         {
  1049.           tempRect.left = SMALLICONWIDTH*3-3;          /* Pin at left edge after number icon */
  1050.           Index -= SMALLICONWIDTH*3-3;
  1051.         }
  1052.  
  1053.       HideControl(HControl);                         /* Hide it during size and move */
  1054.       SizeControl(HControl, Index,16);               /* Make it 16 pixels high, std width */
  1055.       MoveControl(HControl, tempRect.left-1,temp2Rect.bottom - temp2Rect.top-15);/* Size it correctly */
  1056.       ShowControl(HControl);                         /* Safe to show it now */
  1057.       ValidRect(&(*HControl)->contrlRect);           /* Notify Window Manager that it's been drawn */
  1058.       HUnlock((Handle)HControl);                     /* Let it float again */
  1059.     }
  1060. }
  1061.  
  1062.  
  1063. /*
  1064.   Resize Vertical scrollbars.
  1065. */
  1066.  
  1067. ScrollVControl(VControl,whichWindow)
  1068. ControlHandle VControl;
  1069. WindowPtr whichWindow;
  1070. {
  1071.   Rect tempRect, temp2Rect;
  1072.   short Index;
  1073.  
  1074.   if (VControl != NIL)                               /* Only do if the control is valid */
  1075.     {
  1076.       HLockHigh((Handle)VControl);                   /* Lock the handle while we use it */
  1077.       tempRect = (*VControl)->contrlRect;            /* Get the last control position */
  1078.       tempRect.top = tempRect.left - 4;              /* Widen the area to update */
  1079.       tempRect.right = tempRect.bottom + 16;         /* Widen the area to update */
  1080.       InvalRect(&tempRect);                          /* Flag old position for update routine */
  1081.       tempRect = (*VControl)->contrlRect;            /* Get the last control position */
  1082.       temp2Rect = whichWindow->portRect;             /* Get the window rectangle */
  1083.       Index = temp2Rect.bottom - temp2Rect.top - 13; /* Get the scroll area width */
  1084.       tempRect.top = 0;                              /* Pin at left edge */
  1085.       HideControl(VControl);                         /* Hide it during size and move */
  1086.       SizeControl(VControl, 16, Index);               /* Make it 16 pixels high, std width */
  1087.       MoveControl(VControl, temp2Rect.right - temp2Rect.left-15,tempRect.top-1);/* Size it correctly */
  1088.       ShowControl(VControl);                         /* Safe to show it now */
  1089.       ValidRect(&(*VControl)->contrlRect);           /* Notify Window Manager that it's been drawn */
  1090.       HUnlock((Handle)VControl);                     /* Let it float again */
  1091.     }
  1092. }
  1093.  
  1094.  
  1095.  
  1096. /****************************************************************************
  1097.  
  1098.     Moving windows.
  1099.     
  1100. ****************************************************************************/
  1101.  
  1102.  
  1103. /*
  1104.   Move the window.
  1105.   Screen and depth may have changed.
  1106. */
  1107.  
  1108. MoveTheWindow(whichWindow)
  1109. WindowPtr  whichWindow;
  1110. {
  1111.   WindowPtr  SavePort;
  1112.  
  1113.   GetPort(&SavePort);
  1114.   SetPort(whichWindow);
  1115.   SetPort(SavePort);
  1116. }
  1117.  
  1118.  
  1119.  
  1120. /****************************************************************************
  1121.  
  1122.     Updating windows.
  1123.     
  1124. ****************************************************************************/
  1125.  
  1126.  
  1127. /*
  1128.   Update a window.
  1129. */
  1130.  
  1131. UpdateTheWindow(whichWindow)
  1132. WindowPtr  whichWindow;
  1133. {
  1134.   WindowPtr  SavePort;
  1135.   int windex;
  1136.   
  1137.   if(whichWindow == (WindowPtr) -1)
  1138.     whichWindow = FrontWindow();
  1139.  
  1140.   windex = findMyWindow(whichWindow);
  1141.  
  1142.   GetPort(&SavePort);                      /* Save the current port */
  1143.   SetPort(whichWindow);                    /* Set the port to the window */
  1144.  
  1145.   BeginUpdate(whichWindow);
  1146.       
  1147.   if (isLegalWindow(windex))
  1148.     {
  1149.       if(iconic(windex))
  1150.         UpdateIconWindow(whichWindow);
  1151.       else
  1152.         {
  1153.           /* Update Controls and Grow Icon */
  1154.           DrawGrowIcon(whichWindow);
  1155.           DrawControls(whichWindow);
  1156.           DrawGoferIcons(windex);
  1157.  
  1158.           /* Update TE Area */
  1159.           if (TEHANDLE(windex) != NIL)
  1160.             TEUpdate(&(*TEHANDLE(windex))->viewRect,TEHANDLE(windex));
  1161.       }
  1162.  
  1163.     }
  1164.   else
  1165.     {
  1166.       /* Update Controls and Grow Icon */
  1167.       DrawGrowIcon(whichWindow);
  1168.       DrawControls(whichWindow);
  1169.     }
  1170.  
  1171.  
  1172.   EndUpdate(whichWindow);
  1173.   SetPort(SavePort);                       /* Restore the old port */
  1174. }
  1175.  
  1176.  
  1177.  
  1178. /*
  1179.     Update an iconic window.
  1180. */
  1181.  
  1182. UpdateIconWindow(whichWindow)
  1183. WindowPtr whichWindow;
  1184. {
  1185.   Rect r, pr;
  1186.   int windex = findMyWindow(whichWindow);
  1187. #if 0
  1188.   int nwidth = stringwidth(FILENAME(windex)),
  1189.       centre;
  1190. #endif
  1191.  
  1192.   InitWIcon();
  1193.   
  1194.   if(CWindowIcon == NIL && WindowIcon == NIL)
  1195.     return;
  1196.   
  1197.   pr = ((GrafPtr)whichWindow)->portRect;
  1198.  
  1199.   SetRect(&r,0,0,32,32);
  1200.   
  1201.   if(CIAvailable && CWindowIcon != NIL)
  1202.     PlotCIcon(&r,CWindowIcon);
  1203.   else
  1204.     PlotIcon(&r,WindowIcon);
  1205.   
  1206. #if 0
  1207.   centre = pr.right-pr.left;
  1208.  
  1209.   ClipRect(&qd.screenBits.bounds);
  1210.   SetRect(&r,(centre-nwidth-3)/2+pr.left,pr.bottom,
  1211.              (centre+nwidth+3)/2+pr.left,pr.bottom+12);
  1212.   EraseRect(&r);
  1213.   TextFont(0);
  1214.   TextSize(0);
  1215.   MoveTo((centre-nwidth)/2+pr.left,pr.bottom+10);
  1216.   drawstring(FILENAME(windex));
  1217. #endif
  1218. }
  1219.  
  1220.  
  1221.  
  1222. /****************************************************************************
  1223.  
  1224.     Activating windows.
  1225.     
  1226. ****************************************************************************/
  1227.  
  1228. /*
  1229.   Activate or deactivate a window.
  1230.   
  1231.   Changed to handle interpreter-created windows also.
  1232. */
  1233.  
  1234. ActivateTheWindow(whichWindow,activate)
  1235. WindowPtr  whichWindow;
  1236. int activate;
  1237. {
  1238.   WindowPtr  SavePort;                                /* Place to save the last port */
  1239.   int windex = findMyWindow(whichWindow);
  1240.   extern Boolean wrappedround;
  1241.   
  1242.   wrappedround = FALSE;
  1243.  
  1244.   if (isLegalWindow(windex))                         /* Only do if the window is ours */
  1245.    {
  1246.      cantundo();
  1247.      GetPort(&SavePort);                            /* Save the current port */
  1248.      SetPort(whichWindow);                          /* Set the port to my window */
  1249.  
  1250.      if(iconic(windex))
  1251.        {
  1252.          UpdateIconWindow(whichWindow);
  1253.          SetMenus(activate,windex);
  1254.      thefrontwindow = activate?windex:ILLEGAL_WINDOW;
  1255.        }
  1256.  
  1257.      else
  1258.        {
  1259.          DrawGrowIcon(whichWindow);                     /* Draw the grow Icon */
  1260.  
  1261.          SetMenus(activate,windex);
  1262.       
  1263.          if (activate)
  1264.             {
  1265.                  char theFontName[256];
  1266.         TEHandle theInput;
  1267.               
  1268.         DrawGoferIcons(windex);
  1269.               
  1270.         /* Show scroll bars */
  1271.         ScrollHControl(HSCROLL(windex),whichWindow);
  1272.         ScrollVControl(VSCROLL(windex),whichWindow);
  1273.               
  1274.         thefrontwindow = windex;
  1275.         theInput = TEHANDLE(windex);
  1276.               
  1277.         /* Set font name and size in the font menu */
  1278.         getfontname((*theInput)->txFont,theFontName);
  1279.         setfontsize((*theInput)->txSize);
  1280.         setnewfont(0,theFontName);
  1281.               
  1282.         /* Activate TextEdit only after font info is set */
  1283.         TEActivate(theInput);
  1284.         }
  1285.          else
  1286.        { 
  1287.         /* Deactivate the Textedit area */
  1288.         if (thefrontwindow != ILLEGAL_WINDOW && TEHANDLE(thefrontwindow) != NIL)
  1289.           TEDeactivate(TEHANDLE(thefrontwindow));
  1290.         thefrontwindow = ILLEGAL_WINDOW;
  1291.               
  1292.         /* Hide scroll bars */
  1293.         if(HSCROLL(windex)!=NIL)
  1294.           {
  1295.             HideControl(HSCROLL(windex));
  1296.             EraseGoferIcons(windex);
  1297.           }
  1298.               
  1299.         if(VSCROLL(windex)!=NIL)
  1300.         HideControl(VSCROLL(windex));
  1301.         }
  1302.     }
  1303.  
  1304.      SetPort(SavePort);                             /* Restore the old port */
  1305.      InitCursor();
  1306.     }
  1307.  
  1308.   else
  1309.     thefrontwindow = ILLEGAL_WINDOW;
  1310.     
  1311.   AdjustMenus(TRUE);
  1312.     
  1313. }
  1314.  
  1315.  
  1316. /****************************************************************************
  1317.  
  1318.     Window-specific menu handling.
  1319.     
  1320. ****************************************************************************/
  1321.  
  1322.  
  1323. /*
  1324.    Disable or enable a menu item.
  1325.    Used to provide context-sensitivity.
  1326. */
  1327.  
  1328. disablemenuitem(disable,menu,item)
  1329. Boolean disable;
  1330. MenuHandle menu;
  1331. short item;
  1332. {
  1333.   if(disable)
  1334.     DisableItem(menu,item);
  1335.   else
  1336.     EnableItem(menu,item);
  1337. }
  1338.  
  1339.  
  1340. /*
  1341.    Enable/Disable menus appropriate to windex being
  1342.    activated/deactivated.
  1343.    
  1344.    Check/Uncheck the window name in the window menu.
  1345. */
  1346.  
  1347. SetMenus(activate,windex)
  1348. int activate;
  1349. int windex;
  1350. {
  1351.   if(windex == worksheet)
  1352.     {
  1353.       disablemenuitem(activate,Menu_File,MItem_Close);
  1354.  
  1355.       disablemenuitem(activate&&VIRGIN(worksheet),Menu_File,MItem_Save);
  1356.       disablemenuitem(activate&&VIRGIN(worksheet),Menu_File,MItem_Revert_to_Saved);
  1357.     }
  1358.  
  1359.   else if (windex == scrap)
  1360.     {
  1361.       disablemenuitem(activate,Menu_File,MItem_Save);
  1362.       disablemenuitem(activate,Menu_File,MItem_Save_As);
  1363.       disablemenuitem(activate,Menu_File,MItem_Revert_to_Saved);
  1364.       disablemenuitem(activate,Menu_File,MItem_Print);
  1365.  
  1366.       disablemenuitem(activate,Menu_Find,MItem_Find_Replace);
  1367.       disablemenuitem(activate,Menu_Find,MItem_Find_Again);
  1368.       disablemenuitem(activate,Menu_Find,MItem_Find_Backwards);
  1369.       disablemenuitem(activate,Menu_Find,MItem_Replace_Again);
  1370.    }
  1371.  
  1372.  if(activate && OPEN(windex))
  1373.    setitem(Menu_Window,MItem_Iconise,iconic(windex)?"DeIconise":"Iconise");
  1374.  
  1375.  if((iconic(windex) || isEditWindow(windex)) && OPEN(windex))
  1376.    {
  1377.      char wtitle[256];
  1378.      short menuitem;
  1379.           
  1380.      getwtitle(WINDOW(windex),wtitle);
  1381.      menuitem = findmenuitem(Menu_Window,3,1024,wtitle);
  1382.      CheckItem(Menu_Window,menuitem,activate);
  1383.    }
  1384. }
  1385.  
  1386.  
  1387. /****************************************************************************
  1388.  
  1389.     Locating and processing events for a window.
  1390.     
  1391. ****************************************************************************/
  1392.  
  1393.  
  1394. /*
  1395.   Handle mouse events in this window.
  1396. */
  1397.  
  1398. DoTheWindow(eventWindow,myEvent)
  1399. WindowPtr  eventWindow;
  1400. EventRecord    *myEvent;
  1401. {
  1402.   short  code;
  1403.   Point  myPt;
  1404.   WindowPtr  whichWindow;
  1405.   ControlHandle  theControl;
  1406.   int windex = findMyWindow(eventWindow);
  1407.  
  1408.   if (isLegalWindow(windex))
  1409.     {          
  1410.       /* What happened, where */
  1411.       code = FindWindow(myEvent->where, &whichWindow);
  1412.  
  1413.       if ((myEvent->what == mouseDown) && (eventWindow == whichWindow))
  1414.         {
  1415.       if(iconic(windex))
  1416.         {
  1417.           EventRecord mouseUpRec, mouseDownRec;
  1418.           long tc = TickCount(), dbltime = GetDblTime();
  1419.           thefrontwindow = windex;
  1420.           
  1421.           do {
  1422.             if(!GetNextEvent(mUpMask,&mouseUpRec))
  1423.           mouseUpRec.what == nullEvent;
  1424.               } while(mouseUpRec.what == nullEvent && 
  1425.                   mouseUpRec.when < tc+dbltime);
  1426.  
  1427.               if( mouseUpRec.when < tc+dbltime)
  1428.             {
  1429.               while((tc=TickCount()) < mouseUpRec.when+dbltime+20)
  1430.                 {
  1431.                if(EventAvail(mDownMask,&mouseDownRec))
  1432.                  {
  1433.                    if(mouseDownRec.when-mouseUpRec.when <= dbltime)
  1434.                      {
  1435.                        GetNextEvent(mDownMask,&mouseDownRec);
  1436.                          DeIconiseWindow(windex);
  1437.                    return;
  1438.                  }
  1439.                   }
  1440.                  }
  1441.          }
  1442.  
  1443.           /* If no double click, drag the window */
  1444.           SelectWindow(whichWindow);
  1445.           DoDrag(whichWindow);
  1446.           return;
  1447.         }
  1448.         
  1449.      /* Activate the window if necessary */
  1450.      if(WINDOW(windex) != FrontWindow())
  1451.         {
  1452.                SelectWindow(whichWindow);
  1453.            return;
  1454.         }
  1455.  
  1456.       /* Set the GrafPtr */ 
  1457.       SetPort(whichWindow);
  1458.  
  1459.       /* Make the mouse position relative to the current window */
  1460.           myPt = myEvent->where;
  1461.           GlobalToLocal(&myPt);
  1462.       
  1463.       if(PtInRect(myPt,&((*TEHANDLE(windex))->viewRect)))
  1464.         {
  1465.  
  1466.               if (TEHANDLE(windex) != NIL && isEditWindow(windex))
  1467.         {
  1468.           Boolean shift = (myEvent->modifiers & shiftKey) != 0;
  1469.           TEClick(myPt, shift, TEHANDLE(windex));
  1470.           cantundo();          /* Once we've clicked, we can't undo */
  1471.         }
  1472.  
  1473.            thefrontwindow = windex;
  1474.            return;
  1475.          }
  1476.        }
  1477.  
  1478.       if ((eventWindow == whichWindow) && (code == inContent))
  1479.         {
  1480.       Rect lockrect, litrect, numrect;
  1481.       Rect pr = WINDOW(windex)->portRect;
  1482.  
  1483.       SetRect(&lockrect,0,pr.bottom-SMALLICONWIDTH,
  1484.                         SMALLICONWIDTH,pr.bottom);
  1485.  
  1486.       SetRect(&litrect,SMALLICONWIDTH,pr.bottom-SMALLICONWIDTH,
  1487.                        SMALLICONWIDTH*2,pr.bottom);
  1488.  
  1489.       SetRect(&numrect,SMALLICONWIDTH*2,pr.bottom-SMALLICONWIDTH,
  1490.                        SMALLICONWIDTH*3,pr.bottom);
  1491.  
  1492.       /* Has the locked icon been pressed (not for the scrap) */
  1493.       if(isEditWindow(windex) && PtInRect(myPt,&lockrect))
  1494.         InvertLock(windex);
  1495.  
  1496.           /* or, for normal windows the literate or number icon */
  1497.       else if(windex > worksheet && PtInRect(myPt,&litrect))
  1498.         InvertLiterate(windex);
  1499.  
  1500.       else if(windex > worksheet && PtInRect(myPt,&numrect))
  1501.         InvertNumber(windex);
  1502.  
  1503.       /* If not, handle the scrolling */
  1504.       else
  1505.         {
  1506.           /* Handle scrolling */
  1507.               code = FindControl(myPt, whichWindow, &theControl);
  1508.               DoScroll((short) code,myPt,theControl==VSCROLL(windex));
  1509.         }
  1510.         }
  1511.     }
  1512.   else
  1513.     SetPort(whichWindow);
  1514. }
  1515.  
  1516.  
  1517.  
  1518. /****************************************************************************
  1519.  
  1520.     Handling the small icons in the horizontal scrollbar.
  1521.     
  1522. ****************************************************************************/
  1523.  
  1524.  
  1525. /*
  1526.     Draw the small locked icon.  This is either
  1527.     
  1528.     Padlock        Finder Locked File
  1529.     Pencil        Writable
  1530.     No Pencil    Locked Volume or no write access permission
  1531. */
  1532.  
  1533. DrawLockedIcon(windex)
  1534. int windex;
  1535. {
  1536.   Rect ir = (*HSCROLL(windex))->contrlRect;
  1537.   Rect nr = WINDOW(windex)->portRect;
  1538.   static Handle vlicon = NIL, flicon = NIL, ulicon = NIL;
  1539.   Handle icon;
  1540.   BitMap iconbm;
  1541.  
  1542.   if(!isEditWindow(windex) || iconic(windex))
  1543.     return;
  1544.     
  1545.   if(vlicon==NIL)
  1546.     vlicon = GetResource('SICN',Res_IconVLocked);
  1547.  
  1548.   if(flicon==NIL)
  1549.     flicon = GetResource('SICN',Res_IconFLocked);
  1550.  
  1551.   if(ulicon==NIL)
  1552.     ulicon = GetResource('SICN',Res_IconUnlocked);
  1553.  
  1554.   SetPort(WINDOW(windex));
  1555.  
  1556.   nr.left = -1;                        /* Set the icon rect to the left of the window */
  1557.   nr.right = SMALLICONWIDTH-1;
  1558.   nr.top = nr.bottom-SMALLICONWIDTH;
  1559.   
  1560.   ir.left = 0;
  1561.   ir.right = SMALLICONWIDTH;
  1562.   ir.top = 0;
  1563.   ir.bottom = SMALLICONWIDTH;
  1564.   
  1565.   icon = VLOCKED(windex)? vlicon: FLOCKED(windex)? flicon: ulicon;
  1566.  
  1567.   HLock(icon); 
  1568.   iconbm.baseAddr = *icon;
  1569.   iconbm.rowBytes = 2;
  1570.   SetRect(&(iconbm.bounds),0,0,SMALLICONWIDTH,SMALLICONWIDTH);
  1571.   
  1572.   CopyBits(&iconbm,&(WINDOW(windex)->portBits),&ir,&nr,srcCopy,0);
  1573.   HUnlock(icon);
  1574.   OffsetRect(&nr,0,1);
  1575.   FrameRect(&nr);
  1576. }
  1577.  
  1578. /*
  1579.     Erase the locked icon area.
  1580. */
  1581.  
  1582. EraseLockedIcon(windex)
  1583. int windex;
  1584. {
  1585.   Rect nr = WINDOW(windex)->portRect;
  1586.  
  1587.   /* Not for scrap/icon windows */
  1588.   if(!isEditWindow(windex) || iconic(windex))
  1589.     return;
  1590.     
  1591.   nr.left = -1;                        /* Set the icon rect to the left of the window */
  1592.   nr.right = SMALLICONWIDTH-1;
  1593.   nr.top = nr.bottom-SMALLICONWIDTH;
  1594.   EraseRect(&nr);
  1595.   OffsetRect(&nr,0,1);
  1596.   FrameRect(&nr);
  1597. }
  1598.  
  1599.  
  1600. InvertLock(windex)
  1601. int windex;
  1602. {
  1603.    if(FILENAME(windex) == NIL)
  1604.      return;
  1605.  
  1606.    /* Can only lock editablw windows */     
  1607.    if(!isEditWindow(windex) || iconic(windex))
  1608.      return;
  1609.      
  1610.    if(isVolLocked(VREFNUM(windex),DIRID(windex)))
  1611.      FLAGS(windex) = (FLAGS(windex) | WVLOCKED) & ~WFLOCKED;
  1612.  
  1613.    else
  1614.      {
  1615.        if(FLOCKED(windex))
  1616.          {
  1617.            if (isUserLocked(FILENAME(windex),VREFNUM(windex),DIRID(windex)))
  1618.              SetFileLock(FILENAME(windex),VREFNUM(windex),DIRID(windex),FALSE);
  1619.          }
  1620.  
  1621.         else
  1622.          {
  1623.            if (!isUserLocked(FILENAME(windex),VREFNUM(windex),DIRID(windex)))
  1624.              SetFileLock(FILENAME(windex),VREFNUM(windex),DIRID(windex),TRUE);
  1625.      }
  1626.  
  1627.         if (isUserLocked(FILENAME(windex),VREFNUM(windex),DIRID(windex)))
  1628.           FLAGS(windex) = (FLAGS(windex) | WFLOCKED) & ~WVLOCKED;
  1629.     else
  1630.       FLAGS(windex) &= ~WLOCKED;
  1631.      }
  1632.  
  1633.    DrawLockedIcon(windex);
  1634. }
  1635.  
  1636.  
  1637. SetFileLock(name,volrefnum,dirID,lock)
  1638. char *name;
  1639. short volrefnum;
  1640. long dirID;
  1641. Boolean lock;
  1642. {
  1643.   HFileParam finfo;
  1644.   char fname[256];
  1645.   
  1646.   strcpy(fname,name);
  1647.   
  1648.   finfo.ioCompletion = NIL;
  1649.   finfo.ioNamePtr = c2pstr(fname);
  1650.   finfo.ioVRefNum = volrefnum;
  1651.   finfo.ioFVersNum = 0;
  1652.   finfo.ioFDirIndex = 0;
  1653.   finfo.ioDirID = dirID;
  1654.  
  1655.   if(lock)
  1656.     PBHSetFLock((HParmBlkPtr)&finfo,FALSE);
  1657.   else
  1658.     PBHRstFLock((HParmBlkPtr)&finfo,FALSE);
  1659. }
  1660.  
  1661.  
  1662. /*
  1663.     And similarly for the literate icon
  1664. */
  1665.  
  1666. DrawLiterateIcon(windex)
  1667. int windex;
  1668. {
  1669.   Rect ir = (*HSCROLL(windex))->contrlRect;
  1670.   Rect nr = WINDOW(windex)->portRect;
  1671.   static Handle liticon = NIL, nlicon = NIL;
  1672.   Handle icon;
  1673.   BitMap iconbm;
  1674.   
  1675.   /* Not for worksheet/scrap */
  1676.   if(!isEditWindow(windex) || windex == worksheet || iconic(windex))
  1677.     return;
  1678.  
  1679.   if(liticon==NIL)
  1680.     liticon = GetResource('SICN',Res_IconLiterate);
  1681.  
  1682.   if(nlicon==NIL)
  1683.     nlicon = GetResource('SICN',Res_IconNonLiterate);
  1684.  
  1685.   SetPort(WINDOW(windex));
  1686.  
  1687.   nr.left = SMALLICONWIDTH-2;                /* Set the icon rect after the locked icon */
  1688.   nr.right = SMALLICONWIDTH+SMALLICONWIDTH-2;
  1689.   nr.top = nr.bottom-SMALLICONWIDTH;
  1690.   
  1691.   ir.left = 0;
  1692.   ir.right = SMALLICONWIDTH;
  1693.   ir.top = 0;
  1694.   ir.bottom = SMALLICONWIDTH;
  1695.   
  1696.   icon = LITERATE(windex)? liticon: nlicon;
  1697.  
  1698.   HLock(icon); 
  1699.   iconbm.baseAddr = *icon;
  1700.   iconbm.rowBytes = 2;
  1701.   SetRect(&(iconbm.bounds),0,0,SMALLICONWIDTH,SMALLICONWIDTH);
  1702.   
  1703.   CopyBits(&iconbm,&(WINDOW(windex)->portBits),&ir,&nr,srcCopy,0);
  1704.   HUnlock(icon);
  1705.   OffsetRect(&nr,0,1);
  1706.   FrameRect(&nr);
  1707. }
  1708.  
  1709.  
  1710. EraseLiterateIcon(windex)
  1711. int windex;
  1712. {
  1713.   Rect nr = WINDOW(windex)->portRect;
  1714.  
  1715.   /* Not for worksheet/scrap */
  1716.   if(!isEditWindow(windex) || windex == worksheet || iconic(windex))
  1717.     return;
  1718.  
  1719.   nr.left = SMALLICONWIDTH-2;           /* Set the icon rect after the locked icon */
  1720.   nr.right = SMALLICONWIDTH*2-2;
  1721.   nr.top = nr.bottom-SMALLICONWIDTH;
  1722.   EraseRect(&nr);
  1723.   OffsetRect(&nr,0,1);
  1724.   FrameRect(&nr);
  1725. }
  1726.  
  1727.  
  1728. InvertLiterate(windex)
  1729. int windex;
  1730. {
  1731.    if(!isEditWindow(windex) || windex == worksheet || iconic(windex))
  1732.      return;
  1733.  
  1734.    if(LITERATE(windex))
  1735.      FLAGS(windex) &= ~WLITERATE;
  1736.    else
  1737.      FLAGS(windex) |= WLITERATE;
  1738.    DrawLiterateIcon(windex);
  1739.  
  1740.    changed(windex); 
  1741. }
  1742.  
  1743.  
  1744. /*
  1745.     And the number icon
  1746. */
  1747.  
  1748. DrawNumberIcon(windex)
  1749. int windex;
  1750. {
  1751.   Rect ir = (*HSCROLL(windex))->contrlRect;
  1752.   Rect nr = WINDOW(windex)->portRect;
  1753.   static Handle hnumicon = NIL, gnumicon = NIL;
  1754.   Handle icon;
  1755.   BitMap iconbm;
  1756.   
  1757.   /* Not for worksheet/scrap */
  1758.   if(!isEditWindow(windex) || windex == worksheet || iconic(windex))
  1759.     return;
  1760.  
  1761.   if(hnumicon==NIL)
  1762.     hnumicon = GetResource('SICN',Res_IconHaskellNumbers);
  1763.  
  1764.   if(gnumicon==NIL)
  1765.     gnumicon = GetResource('SICN',Res_IconGoferNumbers);
  1766.  
  1767.   SetPort(WINDOW(windex));
  1768.  
  1769.   nr.left = SMALLICONWIDTH*2-3;                /* Set the icon rect after the locked icon */
  1770.   nr.right = SMALLICONWIDTH*3-3;
  1771.   nr.top = nr.bottom-SMALLICONWIDTH;
  1772.   
  1773.   ir.left = 0;
  1774.   ir.right = SMALLICONWIDTH;
  1775.   ir.top = 0;
  1776.   ir.bottom = SMALLICONWIDTH;
  1777.   
  1778.   icon = FLAGS(windex)&WHNUM? hnumicon: gnumicon;
  1779.  
  1780.   HLock(icon); 
  1781.   iconbm.baseAddr = *icon;
  1782.   iconbm.rowBytes = 2;
  1783.   SetRect(&(iconbm.bounds),0,0,SMALLICONWIDTH,SMALLICONWIDTH);
  1784.   
  1785.   CopyBits(&iconbm,&(WINDOW(windex)->portBits),&ir,&nr,srcCopy,0);
  1786.   HUnlock(icon);
  1787.   OffsetRect(&nr,0,1);
  1788.   FrameRect(&nr);
  1789. }
  1790.  
  1791.  
  1792. EraseNumberIcon(windex)
  1793. int windex;
  1794. {
  1795.   Rect nr = WINDOW(windex)->portRect;
  1796.  
  1797.   /* Not for worksheet/scrap */
  1798.   if(!isEditWindow(windex) || windex == worksheet || iconic(windex))
  1799.     return;
  1800.  
  1801.   nr.left = SMALLICONWIDTH*2-3;           /* Set the icon rect after the locked icon */
  1802.   nr.right = SMALLICONWIDTH*3-3;
  1803.   nr.top = nr.bottom-SMALLICONWIDTH;
  1804.   EraseRect(&nr);
  1805.   OffsetRect(&nr,0,1);
  1806.   FrameRect(&nr);
  1807. }
  1808.  
  1809.  
  1810. InvertNumber(windex)
  1811. int windex;
  1812. {
  1813.    if(!isEditWindow(windex) || windex == worksheet || iconic(windex))
  1814.      return;
  1815.  
  1816.    if(FLAGS(windex)&WHNUM)
  1817.      FLAGS(windex) &= ~WHNUM;
  1818.    else
  1819.      FLAGS(windex) |= WHNUM;
  1820.    DrawNumberIcon(windex);
  1821.  
  1822.    changed(windex); 
  1823. }
  1824.  
  1825.  
  1826. DrawGoferIcons(windex)
  1827. int windex;
  1828. {
  1829.   DrawLockedIcon(windex);
  1830.   DrawLiterateIcon(windex);
  1831.   DrawNumberIcon(windex);
  1832. }
  1833.  
  1834.  
  1835. EraseGoferIcons(windex)
  1836. {
  1837.   EraseLockedIcon(windex);
  1838.   EraseLiterateIcon(windex);
  1839.   EraseNumberIcon(windex);
  1840. }
  1841.  
  1842.  
  1843. /****************************************************************************
  1844.  
  1845.     Opening Windows.
  1846.     
  1847. ****************************************************************************/
  1848.  
  1849.  
  1850.  
  1851. /*
  1852.   Open a named window.  Probably DEFUNCT.
  1853. */
  1854.  
  1855. openwindowcalled(name)
  1856. char *name;
  1857. {
  1858.   /* This assumes that the window is on the startup volume -- HSL */
  1859.   openthewindow(findMyWindowName(name,(short)0,(long)0,TRUE));
  1860. }
  1861.  
  1862.  
  1863. /*
  1864.   Open an indexed window.
  1865.  
  1866.   Just select the window if it is legal and "live".
  1867. */
  1868.  
  1869. openthewindow(windex)
  1870. int windex;
  1871. {
  1872.   if(isLegalWindow(windex) && OPEN(windex))
  1873.     {
  1874.       if(iconic(windex))
  1875.     DeIconiseWindow(windex);
  1876.       SelectWindow(WINDOW(windex));
  1877.     }
  1878. }
  1879.  
  1880.  
  1881. /*
  1882.    Make a window the frontmost window.
  1883.    
  1884. */
  1885.  
  1886. windowtofront(windex)
  1887. int windex;
  1888. {
  1889.   WindowPtr w = WINDOW(windex);
  1890.   
  1891.   if(w != FrontWindow())
  1892.     {
  1893.       if(w != thefrontwindow && thefrontwindow != ILLEGAL_WINDOW)
  1894.         ActivateTheWindow(WINDOW(thefrontwindow),FALSE);
  1895.       if(iconic(windex))
  1896.         DeIconiseWindow(windex);
  1897.       SelectWindow(w);
  1898.       updatewindows();
  1899.     }
  1900. }
  1901.  
  1902.  
  1903.  
  1904. /****************************************************************************
  1905.  
  1906.     Showing/Hiding Windows.
  1907.     
  1908. ****************************************************************************/
  1909.  
  1910.  
  1911. HideAllWindows(hide)
  1912. Boolean hide;
  1913. {
  1914.   int i;
  1915.  
  1916.   if(scrapVisible)
  1917.     ShowHide(iconic(scrap)?ICONWINDOW(scrap):WINDOW(scrap),!hide);
  1918.  
  1919.   for(i=NUM_SYS_WINDOWS-1; i < NUM_WINDOWS; ++i)
  1920.     if(OPEN(i))
  1921.        ShowHide(iconic(i)?ICONWINDOW(i):WINDOW(i),!hide);
  1922. }
  1923.